package com.lp.realm;

import com.lp.po.Role;
import com.lp.po.User;
import com.lp.service.RoleService;
import com.lp.service.UserService;
import com.lp.utils.MDUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;


@Component
public class LoginRealm extends AuthorizingRealm{

    @Resource(name = "userServiceImpl")
    private UserService userService;

    @Resource(name = "roleServiceImpl")
    private RoleService roleService;
    User user= null;

    /**
     * 获取身份信息，我们可以在这个方法中，从数据库获取该用户的权限和角色信息
     * 当调用权限验证时，就会调用此方法
     */
    //为登陆用户授予权限和角色
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        String username = (String) getAvailablePrincipal(principalCollection);

        Role role = null;

        try {
            User user = userService.findByName(username);
            //获取角色对象
            role = roleService.findByid(user.getRole());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //通过用户名从数据库获取权限/角色信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        Set<String> r = new HashSet<String>();
        if (role != null) {
            r.add(role.getRolename());
            info.setRoles(r);
        }

        return info;
    }

    /**
     * 在这个方法中，进行身份验证
     *         login时调用
     */
    //验证当前登陆用户
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //使用MD5加密
        //当前realm对象的name(realmName：com.lp.realm.LoginRealm_0)
        String realmName=getName();
        //输入的密码的值 （没有加密）
        String password = new String((char[])token.getCredentials());
        //盐值（username：admin）
        String username = (String) token.getPrincipal();
        //密钥（admin时：YWRtaW4=）  bHVwaW5n
        ByteSource credenttialSalt=ByteSource.Util.bytes(username);
        user=userService.findName(username);
        //设置加密后的密码
        try {
            user.setPassword(MDUtils.getMD5Password(password,credenttialSalt).toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        User users=userService.findUser(user);
        if(users==null){
            throw new UnknownAccountException("用户名或密码错误，请重新填写！");
        }else {
            AuthenticationInfo authInfo = new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),credenttialSalt,realmName);
            return authInfo;
        }
    }
}
